package com.ywl.controller;


import com.ywl.common.BaseContext;
import com.ywl.common.CustomException;
import com.ywl.common.R;
import com.ywl.dto.UserDto;
import com.ywl.entity.User;
import com.ywl.service.UserService;
import com.ywl.utils.SMSUtils;
import com.ywl.utils.ValidateCodeUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpSession;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author ywl
 * @since 2022-08-26
 */
@RestController
@Slf4j
@Api(tags = "用户相关接口")
public class UserController {
    @Autowired
    UserService userService;
    @Autowired
    StringRedisTemplate redisTemplate;

    /**
     * 发送验证码，并把正确的验证码存入到redis当中，
     * key：phone，value：生成的六位验证码
     *
     * @return
     */
    @ApiOperation("发送验证码控制器")
    @PostMapping("/sendyzm")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "phone", value = "用户手机号", required = true)
    })
    public R<String> sendYzm(User user, HttpSession httpSession) {
        String phone = user.getPhone();//获取手机号
        log.info("phone={}", phone);

        if (StringUtils.isEmpty(phone)) {
            throw new CustomException("手机验证码短信发送失败");
        }

        //1.选择redis中的string类型，存入到NoSql当中，并设置过期时间（5分钟）
        String generateValidateCode = ValidateCodeUtils.generateValidateCode(6).toString();
        log.info("code={}", generateValidateCode);
        redisTemplate.opsForValue().set(phone, generateValidateCode, 5L, TimeUnit.MINUTES);

        //把验证码 存入到session，key为phone，如不使用redis，取消一下注释即可
        /*httpSession.setAttribute(phone,generateValidateCode);*/

        //2.发送验证码给手机
        SMSUtils.sendMessage("阿里云短信测试", "SMS_154950909",
                "18581558439", generateValidateCode);;
        return R.success("验证码发送成功，有效时间为5分钟");
    }

    /**
     * 登陆
     *
     * @param userDto
     * @param session
     * @return
     */
    @ApiOperation("登陆方法控制器")
    @PostMapping("/login")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "username", value = "括用户名", required = true),
            @ApiImplicitParam(name = "password", value = "验证码", required = true)
    })
    public R<String> login(UserDto userDto, HttpSession session) {

        //先进行验证码的校验，从redis取出正确的验证码
        String inputCode = userDto.getPassword();
        String phone = userDto.getUsername();//获取手机号

        //取出redis中，key为phone的验证码
        String generateCode = redisTemplate.opsForValue().get(phone);

        //取出session中的验证码，key为phone,如果不使用redis，取消以下注释，把redis相关代码注释掉即可
        /*String generateCode = (String)session.getAttribute(phone);*/

        log.info("redis的验证码={}", generateCode);
        //进行比对
        if (!(StringUtils.isNotEmpty(inputCode)
                && generateCode.equals(inputCode)
                && StringUtils.isNotEmpty(phone))) {
            throw new CustomException("登陆失败，验证码或手机号有误,请重新输入");
        }

        User user = userService.getByPhone(phone);
        if (user == null) {
            //如果用户为空，则进行注册
            user = new User();
            user.setPhone(phone);
            user.setCity("北京");
            boolean save = userService.save(user);
            log.info("用户是否注册成功={}", save);
        }

        //如果用户不为空，查询出来的user则不为null，把用户id存入到ThreadLocal当中，
        //并移除redis中缓存的验证码
        BaseContext.setCurrentId(user.getId());
        redisTemplate.delete(phone);

        //移除session域中的手机号
        //session.removeAttribute(phone);

        //验证码输入正确，发送成功的消息即可
        return R.success("登陆成功");
    }
}

